package org.acghub.mtdb.core;

import org.acghub.mtdb.common.Lifecycle;
import org.acghub.mtdb.common.Mtdb;
import org.acghub.mtdb.common.Pair;
import org.acghub.mtdb.common.exception.LifecycleException;

import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author zhouhe
 */
public abstract class Tables implements Lifecycle<Pair<Mtdb, StorageEngine>> {

    private static int TABLE_ID = 0;
    private static final Map<String, Integer> TABLE_NAME_2_ID = new HashMap<>();
    private final List<Table> tables = new ArrayList<>();
    private final static ReadWriteLock FLUSH_LOCK = new ReentrantReadWriteLock();

    static synchronized int getTableId(String tableName) {
        return TABLE_NAME_2_ID.computeIfAbsent(tableName, k -> ++TABLE_ID);
    }

    static ReadWriteLock getFlushLock() {
        return FLUSH_LOCK;
    }

    static void rFlushLock() throws InterruptedException {
        FLUSH_LOCK.readLock().lockInterruptibly();
    }

    static void rFlushUnlock() {
        FLUSH_LOCK.readLock().unlock();
    }

    static void wFlushLock() throws InterruptedException {
        FLUSH_LOCK.writeLock().lockInterruptibly();
    }

    static void wFlushUnlock() {
        FLUSH_LOCK.writeLock().unlock();
    }

    protected final void addTable(Table table) {
        this.tables.add(table);
    }

    public List<Table> getTables() {
        return Collections.unmodifiableList(tables);
    }

    @Override
    @SuppressWarnings("all")
    public void init(Pair<Mtdb, StorageEngine> pair) throws LifecycleException {
        org.acghub.mtdb.common.Mtdb mtdb = pair.getKey();
        StorageEngine storageEngine = pair.getValue();
        for (Table table : this.tables) {
            table.init(Pair.of(mtdb.getChild(org.acghub.mtdb.common.Table.class, table.name()), storageEngine));
        }
    }

    @Override
    public final void close() throws LifecycleException {
        for (Table table : tables) {
            table.close();
        }
    }
}
